package com.yuxl.admin.common.core.utils;

import jakarta.validation.constraints.Null;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldNameConstants;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.Serial;
import java.io.Serializable;
import java.util.List;

/**
 * 响应信息主体
 *
 * @param <T>
 * @author lengleng
 */
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@FieldNameConstants
public class R<T> implements Serializable {

	@Serial
	private static final long serialVersionUID = 1L;

	private int code;

	private String msg;

	private T data;

	public static <T> Mono<R<T>> ok() {
		return restResult(Mono.empty(), HttpStatus.OK, null);
	}

	public static <T> Mono<R<T>> ok(Mono<T> data) {
		return restResult(data, HttpStatus.OK, null);
	}

	public static <T> Mono<R<List<T>>> ok(Flux<T> data) {
		return restResult(data, HttpStatus.OK, null);
	}

	public static <T> Mono<R<T>> ok(Mono<T> data, String msg) {
		return restResult(data, HttpStatus.OK, msg);
	}

	public static <T> Mono<R<List<T>>> ok(Flux<T> data, String msg) {
		return restResult(data, HttpStatus.OK, msg);
	}

	public static <T> Mono<R<T>> failed() {
		return restResult(Mono.empty(), HttpStatus.INTERNAL_SERVER_ERROR, null);
	}

	public static <T> Mono<R<T>> failed(String msg) {
		return restResult(Mono.empty(), HttpStatus.INTERNAL_SERVER_ERROR, msg);
	}

	public static <T> Mono<R<T>> failed(Mono<T> data) {
		return restResult(data, HttpStatus.INTERNAL_SERVER_ERROR, null);
	}

	public static <T> Mono<R<List<T>>> failed(Flux<T> data) {
		return restResult(data, HttpStatus.INTERNAL_SERVER_ERROR, null);
	}

	public static <T> Mono<R<T>> failed(Mono<T> data, String msg) {
		return restResult(data, HttpStatus.INTERNAL_SERVER_ERROR, msg);
	}
	public static <T> Mono<R<List<T>>> failed(Flux<T> data, String msg) {
		return restResult(data, HttpStatus.INTERNAL_SERVER_ERROR, msg);
	}

	public static <T> R<T> build(T data, HttpStatus code, String msg) {
		R<T> apiResult = new R<>();
		apiResult.setCode(code.value());
		apiResult.setData(data);
		apiResult.setMsg(msg);
        return apiResult;
	}

	public static <T> Mono<R<T>> restResult(Mono<T> data, HttpStatus code, String msg) {
		return data.map(d -> build(d, code, msg));
	}

	public static <T> Mono<R<List<T>>> restResult(Flux<T> data, HttpStatus code, String msg) {
		return data.collectList().map(d -> build(d, code, msg));
	}



}
